package com.smedi.ismedi.constructionproject.core.domain.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.smedi.ismedi.constructionproject.core.domain.aggregatemodel.ProjectAssignment;
import com.smedi.ismedi.constructionproject.core.domain.repository.ProjectAssignmentRepository;
import com.smedi.ismedi.constructionproject.core.domain.service.ProjectAssignmentDomainService;
import com.smedi.ismedi.constructionproject.core.domain.service.ProjectBasicDomainService;
import com.smedi.ismedi.constructionproject.core.infrastructure.constant.CustomError;
import com.smedi.ismedi.constructionproject.core.port.adapter.persistence.model.ProjectAssignmentEntity;
import com.smedi.ismedi.constructionproject.core.port.adapter.persistence.mybatis.mapper.ProjectAssignmentMapper;
import com.smedi.ismedi.constructionproject.core.port.adapter.service.OrganizationRemoteApiService;
import com.smedi.ismedi.organization.api.dto.response.ProjectOrganizationResponse;
import com.smedi.ismedi.web.starter.exception.LogicException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * @Author: xulinjun
 * @Date: 2021-6-24 15:36
 */
@Slf4j
@Service
@AllArgsConstructor
public class ProjectAssignmentDomainServiceImpl implements ProjectAssignmentDomainService {
    private final ProjectAssignmentRepository projectAssignmentRepository;

    private final ProjectBasicDomainService projectBasicDomainService;

    private final OrganizationRemoteApiService organizationRemoteApiService;

    private final ProjectAssignmentMapper projectAssignmentMapper;

    // 因事务限制，故不校验人员是否存在
    @Override
    public ProjectAssignment saveAssignment(ProjectAssignment data) {
        ProjectAssignment basic;
        if (data.getProjectAssignmentId() != null) {
            basic = projectAssignmentRepository.selectByProjectAssignmentId(data.getProjectAssignmentId());
            if (basic == null) {
                throw LogicException.raise(CustomError.PROJECT_ASSIGNMENT_NOT_EXIST);
            }
        } else {
            basic = new ProjectAssignment();
        }

        LambdaQueryWrapper<ProjectAssignmentEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ProjectAssignmentEntity::getProjectId,data.getProjectId());
        lambdaQueryWrapper.eq(ProjectAssignmentEntity::getPersonId,data.getPersonId());
        lambdaQueryWrapper.eq(ProjectAssignmentEntity::getProjectOrganizationId,data.getProjectOrganizationId());
        projectAssignmentMapper.delete(lambdaQueryWrapper);

        // 检查当前项目是否生效
        if (!projectBasicDomainService.validateProject(data.getProjectId())) {
            throw LogicException.raise(CustomError.PROJECT_NOT_AVAILABLE);
        }

        // 检查当前项目组织是否有效
        ProjectOrganizationResponse projectOrganization = organizationRemoteApiService.getProjectOrganizationView(data.getProjectOrganizationId());
        if (projectOrganization != null) {
            if (!data.getProjectId().equals(projectOrganization.getProjectId())) {
                throw LogicException.raise(CustomError.PROJECT_ORGANIZATION_NOT_BELONG_PROJECT);
            }
        } else {
            throw LogicException.raise(CustomError.ORG_NOT_AVAILABLE);
        }

        basic.setProjectId(data.getProjectId())
                .setProjectJob(data.getProjectJob())
                .setPersonId(data.getPersonId())
                .setProjectOrganizationId(data.getProjectOrganizationId());

        // 保存数据
        ProjectAssignment domain = (data.getProjectAssignmentId() == null) ? projectAssignmentRepository.doInsert(basic) : projectAssignmentRepository.doUpdate(basic);
        return domain;
    }

    @Override
    public Boolean duplicateAssignment(Long personId, Long projectId, Long projectOrganizationId) {
        return projectAssignmentRepository.selectCountByPersonIdAndProjectIdAndProjectOrganizationId(personId, projectId, projectOrganizationId) > 0;
    }

    @Override
    public void deleteAssignment(Long projectAssignmentId) {
        ProjectAssignment projectAssignment = projectAssignmentRepository.selectByProjectAssignmentId(projectAssignmentId);
        if (projectAssignment != null) {
            projectAssignmentRepository.doDelete(projectAssignmentId);
        } else {
            throw LogicException.raise(CustomError.PROJECT_ASSIGNMENT_NOT_EXIST);
        }
    }

    @Override
    public void doDeleteByPersonIdAndProjectId(Long personId,Long projectId) {
        projectAssignmentRepository.doDeleteByPersonIdAndProjectId(personId,projectId);
    }
    @Override
    public void doDeleteByPersonId(Long personId) {
        projectAssignmentRepository.doDeleteByPersonId(personId);
    }

    @Override
    public Boolean validateProjectOrganizationHasAssignment(Long projectOrganizationId) {
        return projectAssignmentRepository.selectCountByProjectOrganizationId(projectOrganizationId) > 0;
    }

    @Override
    public void deleteAssignmentByProjectId(Long projectId) {
        projectAssignmentRepository.doDeleteByProjectId(projectId);
    }

    @Override
    public void editProjectAssignment(ProjectAssignment projectAssignment) {
        projectAssignmentRepository.saveProjectAssignment(projectAssignment);
    }
}
